#ifndef VL_MAP_PROP__H_
#define VL_MAP_PROP__H_

#include <functional>
#include "vl_prop.h"

/**
 * @Author: CimZzz
 * @Date: 2022-07-29 18:23:08
 * 
 * 快速遍历 MapProp 宏定义
 */
#define VL_MAP_PROP_FOREACH(mapProp, codeblock) mapProp->foreach([&](const std::string& key, const std::shared_ptr<VLProp>& value) -> bool codeblock);

namespace VL {

/**
 * @Author: CimZzz
 * @Date: 2022-06-21 15:45:49
 * 
 * 映射表属性
 */
class MapProp : public VLProp {
protected:
	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 15:46:14
	 * 
	 * 供 RootProp 使用的构造方法
	 */
	explicit MapProp(VLProp::PropType type);

public:
	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-13 14:47:21
	 * 
	 * 定义遍历语句
	 * @param 1 key
	 * @param 2 value
	 * @return 如果中断遍历返回 false
	 */
	using ForEachFunc = std::function<bool(const std::string &, std::shared_ptr<VLProp>)>;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 15:46:14
	 * 
	 * 构造方法
	 */
	explicit MapProp();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 15:46:29
	 * 
	 * 构造方法
	 * @param name 属性名
	 */
	explicit MapProp(std::string name);


	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-16 20:13:24
	 * 
	 * 获取子节点
	 * 
	 * @param name 节点名
	 * 
	 * @return 子节点, 如果不存在则会返回空节点
	 */
	std::shared_ptr<VLProp> operator [](const std::string& name);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-10 16:05:01
	 * 
	 * 获取子节点
	 * 
	 * @param name 节点名
	 * 
	 * @return 子节点, 如果不存在则会返回空节点
	 */
	std::shared_ptr<VLProp> get(const std::string& name);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-16 20:13:24
	 * 
	 * 设置子节点, 直接设置节点值
	 * 
	 * @param name 节点名
	 * @param value 节点值
	 */
	void operator ()(const std::string& name, const std::string& value);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-16 20:13:24
	 * 
	 * 设置子节点
	 * 
	 * @param name 节点名
	 * @param prop 节点指针
	 */
	void operator ()(const std::string& name, VLProp* prop);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-16 20:13:24
	 * 
	 * 设置子节点
	 * 
	 * @param name 节点名
	 * @param prop 节点智能指针
	 */
	void operator ()(const std::string& name, const std::shared_ptr<VLProp>& prop);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-10 16:09:02
	 * 
	 * 设置子节点
	 * 
	 * @param name 节点名
	 * @param value 节点值
	 */
	void push(const std::string& name, const std::string& value);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-10 16:10:10
	 * 
	 * 设置子节点
	 * 
	 * @param name 节点名
	 * @param prop 节点指针
	 */
	void push(const std::string& name, VLProp* prop);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-10 16:17:03
	 * 
	 * 设置子节点
	 * 
	 * @param name 节点名
	 * @param prop 节点智能指针
	 */
	void push(const std::string& name, const std::shared_ptr<VLProp>& prop);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 15:25:58
	 * 
	 * 删除指定属性名元素
	 * 
	 * @param name 属性名
	 * 
	 * @return 当前映射表引用属性
	 */
	MapProp& operator -(const std::string& name);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-10 16:21:09
	 * 
	 * 删除指定属性名元素
	 * 
	 * @param name 属性名
	 * 
	 * @return 当前映射表引用属性
	 */
	void remove(const std::string& name);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-13 14:48:07
	 * 
	 * 遍历 Map
	 * @param func 遍历函数
	 */
	void foreach(ForEachFunc func);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-25 20:08:16
	 * 
	 * 克隆当前属性
	 * 
	 * @return 属性指针
	 */
	virtual VLProp* clone();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-30 19:14:40
	 * 
	 * 组合属性
	 * @param prop 属性指针
	 * 
	 * @return 组合成功返回 false
	 */
	virtual bool combine(std::shared_ptr<VLProp>& prop);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-04 17:55:29
	 * 
	 * 获取当前尺寸
	 * @return 当前尺寸
	 */
	unsigned int size();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 15:57:31
	 * 
	 * 清空全部属性
	 */
	void clear();
	
	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-30 18:22:06
	 * 
	 * 比较两个 Array 之间的区别
	 * @param prop 属性指针
	 * @return 如果相同返回 true
	 */
	virtual bool diff(VLProp* prop);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 11:04:46
	 * 
	 * 构建属性打印信息
	 */
	virtual std::string buildPropPrintInfo();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 15:16:41
	 * 
	 * 打印属性节点信息, 设置前缀
	 * @param prefix 前缀
	 */
	virtual void printWithPrefix(std::string prefix);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-19 18:10:42
	 * 
	 * 获取 Map 的起始迭代器
	 * 
	 * @return Map 的起始迭代器
	 */
	std::map<std::string, std::shared_ptr<VLProp>>::iterator begin();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-19 18:10:42
	 * 
	 * 获取 Map 的终止迭代器
	 * 
	 * @return Map 的终止迭代器
	 */
	std::map<std::string, std::shared_ptr<VLProp>>::iterator end();

private:
	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 17:51:55
	 * 
	 * 友元类
	 */
	friend class RootProp;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-16 20:10:59
	 * 
	 * 属性节点列表
	 */
	std::map<std::string, std::shared_ptr<VLProp>> children;

};


}

#endif // VL_MAP_PROP__H_
